package com.pxt.demo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

public class TouchView extends View {

    private float downX = 0, downY = 0, moveX = 0, moveY = 0;
    private float scale = 1;
    private float angle = 0;
    private float rotate = 0;
    private float dist;
    private Paint paint;
    private Bitmap pic;
    private Matrix matrix = new Matrix();
    private PointF centerPoint;
    private boolean multi = false;


    public TouchView(Context context) {
        this(context, null, 0, 0);
    }

    public TouchView(Context context, @Nullable AttributeSet attrs) {
        this(context, null, 0, 0);
    }

    public TouchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, null, 0, 0);
    }

    public TouchView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setColor(Color.BLACK);
        pic = BitmapFactory.decodeResource(getResources(), R.mipmap.pic);
        centerPoint = new PointF(pic.getWidth() / 2, pic.getHeight() / 2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        matrix.postTranslate(moveX, moveY);
        matrix.postScale(scale, scale, centerPoint.x, centerPoint.y);
        matrix.postRotate(rotate, centerPoint.x, centerPoint.y);
        canvas.drawBitmap(pic, matrix, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                multi = false;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                multi = true;
                dist = dist(event);
                angle = angle(event);
                midPoint(event);
                break;
            case MotionEvent.ACTION_MOVE:
                if (multi) {
                    float newDist = dist(event);
                    if (newDist != 0 && dist != 0) {
                        // scale
                        scale = newDist / dist;

                        // rotate
                        float newAngle = angle(event);
                        rotate = newAngle - angle;
                        angle = newAngle;
                        dist = newDist;
                    }


                    // move
                    moveX = event.getX() - downX;
                    moveY = event.getY() - downY;
                    downX = event.getX();
                    downY = event.getY();
                }
                invalidate();

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                moveX = 0;
                moveY = 0;
                scale = 1;
                multi = false;
                break;
        }
        return true;
    }

    // 两指间距离
    private float dist(MotionEvent event) {
        if (event.getPointerCount() != 2) return 0;
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

    // 取旋转角度
    private float angle(MotionEvent event) {
        double delta_x = (event.getX(0) - event.getX(1));
        double delta_y = (event.getY(0) - event.getY(1));
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    private void midPoint(MotionEvent event) {
        float x = 0;
        float y = 0;
        for (int i = 0; i < event.getPointerCount(); i++) {
            x += event.getX(i);
            y += event.getY(i);
        }
        centerPoint.set(x / event.getPointerCount(), y / event.getPointerCount());
    }
}
